package ch.ethz.fcl.metrobuzz.render.techniques.stencil;

import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;

import ch.ethz.fcl.metrobuzz.MBContainer;
import ch.ethz.fcl.metrobuzz.controller.MBController;
import ch.ethz.fcl.metrobuzz.viewer.MBViewer;
import ch.ethz.fcl.metrobuzz.viewer.MBViewer.ProjectionType;

public class StenciTest {
	private MBViewer view;
	private MBController control;

	public static void main(String[] args) {
		new StenciTest().run();
	}

	public StenciTest() {
		MBContainer container = new MBContainer();

		int screenWidth = Display.getDesktopDisplayMode().getWidth();
		int screenHeight = Display.getDesktopDisplayMode().getHeight();
		int CANVAS_WIDTH = screenWidth - 300;
		int CANVAS_HEIGHT = (int) (CANVAS_WIDTH * 900.0F / 1440);

		view = new MBViewer(ProjectionType.Ortho, container);

		view.createDisplay(screenWidth, screenHeight, CANVAS_WIDTH,
				CANVAS_HEIGHT, "Accessibility Visualization");
		view.getCamera().initDistance(1.0f);
		view.getCamera().disablePan();

		view.initFrame();

		control = new MBController(container);

		setStencilBuffer();
	}

	public void run() {
		while (!Display.isCloseRequested()) {
			GL11.glPushMatrix();
			view.update();

			if (MBViewer.newUpdate) {
				render();
			}

			control.update();

			GL11.glPopMatrix();

			Display.update();
			Display.sync(32);
		}
		Display.destroy();
		System.exit(0);
	}

	private void render() {
		// clear previous buffers
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
		GL11.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
		
		GL11.glEnable(GL11.GL_STENCIL_TEST);
		GL11.glClear(GL11.GL_STENCIL_BUFFER_BIT);

		GL11.glColorMask(false, false, false, false);

		GL11.glStencilFunc(GL11.GL_ALWAYS, 1, 1);
		GL11.glStencilOp(GL11.GL_REPLACE, GL11.GL_REPLACE, GL11.GL_REPLACE);

		// set paintable for whole screen
		GL11.glBegin(GL11.GL_POLYGON);
		GL11.glVertex3f(-1, -1, 0);
		GL11.glVertex3f(-1, 1, 0);
		GL11.glVertex3f(1, 1, 0);
		GL11.glVertex3f(1, -1, 0);
		GL11.glEnd();

		GL11.glStencilFunc(GL11.GL_ALWAYS, 0, 0);
		GL11.glStencilOp(GL11.GL_REPLACE, GL11.GL_REPLACE, GL11.GL_REPLACE);

		// set not paintable for triangle
		GL11.glBegin(GL11.GL_TRIANGLES);
		GL11.glVertex3f(-0.5f, 0f, 0);
		GL11.glVertex3f(0.5f, 0, 0);
		GL11.glVertex3f(0, 0.5f, 0);
		GL11.glEnd();

		GL11.glColorMask(true, true, true, true);
		GL11.glStencilFunc(GL11.GL_EQUAL, 1, 1);
		GL11.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_KEEP);

		GL11.glColor4f(0.0f, 1.0f, 0, 1);
		GL11.glBegin(GL11.GL_POLYGON);
		GL11.glVertex3f(-0.5f, -0.5f, 0);
		GL11.glVertex3f(0.5f, -0.5f, 0);
		GL11.glVertex3f(0.5f, 0.5f, 0);
		GL11.glVertex3f(-0.5f, 0.5f, 0);
		GL11.glEnd();

		GL11.glColor4f(0.0f, 0.0f, 1, 1);
		GL11.glBegin(GL11.GL_TRIANGLES);
		GL11.glVertex3f(-1f, 0f, 0);
		GL11.glVertex3f(1f, 0, 0);
		GL11.glVertex3f(0, 0.75f, 0);
		GL11.glEnd();

		GL11.glDisable(GL11.GL_STENCIL_TEST);
	}

	private void setStencilBuffer() {
		GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

		GL11.glEnable(GL11.GL_STENCIL_TEST);
		GL11.glClear(GL11.GL_STENCIL_BUFFER_BIT);

		GL11.glColorMask(false, false, false, false);

		GL11.glStencilFunc(GL11.GL_ALWAYS, 1, 1);
		GL11.glStencilOp(GL11.GL_REPLACE, GL11.GL_REPLACE, GL11.GL_REPLACE);

		// set paintable for whole screen
		GL11.glBegin(GL11.GL_POLYGON);
		GL11.glVertex3f(-1, -1, 0);
		GL11.glVertex3f(-1, 1, 0);
		GL11.glVertex3f(1, 1, 0);
		GL11.glVertex3f(1, -1, 0);
		GL11.glEnd();

		GL11.glStencilFunc(GL11.GL_ALWAYS, 0, 0);
		GL11.glStencilOp(GL11.GL_REPLACE, GL11.GL_REPLACE, GL11.GL_REPLACE);

		// set not paintable for triangle
		GL11.glBegin(GL11.GL_TRIANGLES);
		GL11.glVertex3f(-0.5f, 0f, 0);
		GL11.glVertex3f(0.5f, 0, 0);
		GL11.glVertex3f(0, 0.5f, 0);
		GL11.glEnd();

		GL11.glDisable(GL11.GL_STENCIL_TEST);
	}
}
